using System;
using System.Collections.Generic;
using System.Text;
using DTO;
using DAO;
using System.Data;

namespace BUS
{
    /// <summary> 
    ///Author: nnamthach@gmail.com 
    /// <summary>
    public class CategoriesControl
    {
        #region Local Variable
        private CategoriesDataAccess _objDAO;
        #endregion Local Variable

        #region Method
        public CategoriesControl()
        {
            _objDAO = new CategoriesDataAccess();
        }

        public CategoriesInfo Get(
        Int32 ID,
        ref string sErr)
        {
            return _objDAO.Get(
            ID,
            ref sErr);
        }

        public DataTable GetAll(
        ref string sErr)
        {
            return _objDAO.GetAll(
            ref sErr);
        }

        public Int32 Add(CategoriesInfo obj, ref string sErr)
        {
            return _objDAO.Add(obj, ref sErr);
        }
        public Int32 Add_Categories(CategoriesInfo obj, ref string sErr)
        {
            if (IsConstanePro(obj.LinkedID))
            {
                sErr = "Exist Product in Category";
                return -1;
            }
            if (obj.LinkedID != -1)
            {
                CategoriesInfo cateInfo = _objDAO.Get(obj.LinkedID, ref sErr);
                obj.Level = cateInfo.Level + 1;
            }

            return _objDAO.Add(obj, ref sErr);
        }
        public string Update_Categories(CategoriesInfo obj)
        {
            if (IsConstanePro(obj.LinkedID))
            {
                return "Erro: Exist Product in Category";
            }
            string sErr = "";
            CategoriesInfo cateInfoOld = _objDAO.Get(obj.ID, ref sErr);
            if (cateInfoOld.LinkedID != obj.LinkedID)
            {
                if (obj.LinkedID == obj.ID || obj.LinkedID == -1)
                {
                    obj.LinkedID = -1;
                    obj.Level = 0;
                }
                else
                {
                    DataTable dt = _objDAO.GetCategoriesChilds(cateInfoOld.ID, ref sErr);
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        CategoriesInfo tmp = new CategoriesInfo(dt.Rows[i]);
                        if (obj.LinkedID == tmp.ID)
                            return "Erro: Exist Circle Link";
                    }
                    CategoriesInfo cateInfo = _objDAO.Get(obj.LinkedID, ref sErr);
                    obj.Level = cateInfo.Level + 1;
                }
                if (cateInfoOld.Level != obj.Level)
                {
                    Update_CategoriesChilds(obj, ref sErr);
                }
            }
            else
            {
                CategoriesInfo cateInfo = _objDAO.Get(obj.LinkedID, ref sErr);
                if (obj.LinkedID != -1)
                {

                    obj.Level = cateInfo.Level + 1;
                }

                if (cateInfoOld.Level != obj.Level)
                {
                    Update_CategoriesChilds(obj, ref sErr);
                }
            }
            return _objDAO.Update(obj);
        }
        public void Update_CategoriesChilds(CategoriesInfo obj, ref string sErr)
        {
            DataTable dt = _objDAO.GetCategoriesChilds(obj.ID, ref sErr);
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                CategoriesInfo cate = new CategoriesInfo(dt.Rows[i]);
                cate.Level = obj.Level + 1;
                _objDAO.Update(cate);
                Update_CategoriesChilds(cate, ref sErr);
            }
            //return "";
        }
        public bool IsConstanePro(int ID)
        {
            return _objDAO.IsConstanePro(ID);
        }
        public string Update(CategoriesInfo obj)
        {
            return _objDAO.Update(obj);
        }

        public string Delete(
        Int32 ID
        )
        {
            return _objDAO.Delete(
            ID
            );
        }
        public Boolean IsExist(
        Int32 ID
        )
        {
            return _objDAO.IsExist(
            ID
            );
        }

        public DataTableCollection Get_Page(CategoriesInfo obj, string orderBy, int pageIndex, int pageSize, ref String sErr)
        {
            return _objDAO.Get_Page(obj, orderBy, pageIndex, pageSize, ref sErr);
        }

        public DataTable Search(String columnName, String columnValue, String condition, ref String sErr)
        {
            return _objDAO.Search(columnName, columnValue, condition, "", ref  sErr);
        }
        public string InsertUpdate(CategoriesInfo obj)
        {
            string sErr = "";
            if (IsExist(
            obj.ID
            ))
            {
                sErr = Update(obj);
            }
            else
                Add(obj, ref sErr);
            return sErr;
        }

        public DataTable GetTransferOut(string dtb, object from, object to, ref string sErr)
        {
            return _objDAO.GetTransferOut(dtb, from, to, ref sErr);
        }

        public DataTable ToTransferInStruct()
        {
            CategoriesInfo inf = new CategoriesInfo();
            return CategoriesInfo.ToDataTable();
        }

        public string TransferIn(DataRow row)
        {
            CategoriesInfo inf = new CategoriesInfo(row);
            return InsertUpdate(inf);
        }
        public DataTable GetRootsCategories(String Type,ref  string sErr)
        {

            return _objDAO.GetRootsCategories(Type,ref sErr);
        }
        public DataTable get_childs(Int32 ID, ref string sErr)
        {
            return _objDAO.get_child(ID, ref sErr);
        }
        public string Delete_Categories(string arrID)
        {
            string sErr = "";
            String[] test = arrID.Split(',');
            foreach (string strID in test)
            {
                if (strID != "")
                {
                    int ID = Convert.ToInt32(strID);
                    sErr += _objDAO.Delete(ID);
                }
            }
            return sErr;
        }
        public DataTable GetAll_CategoriesChilds(CategoriesInfo cate, ref string sErr)
        {
            DataTable dt = InitTable();
            DataRow row = cate.ToDataRow(dt);
            dt.Rows.Add(row);
            dt = GetAll_CategoriesChildsEx(dt, cate, ref sErr);
            return dt;
        }
        private DataTable GetAll_CategoriesChildsEx(DataTable dt, CategoriesInfo cate, ref string sErr)
        {
            DataTable dtEx = _objDAO.GetCategoriesChilds(cate.ID, ref sErr);
            if (dtEx.Rows.Count > 0)
            {
                dt = ImportTable(dtEx, dt);
                for (int i = 0; i < dtEx.Rows.Count; i++)
                {
                    CategoriesInfo cateEx = new CategoriesInfo(dtEx.Rows[i]);
                    GetAll_CategoriesChildsEx(dt, cateEx, ref sErr);
                }
            }
            return dt;
        }
        private DataTable ImportTable(DataTable dtSour, DataTable dtDes)
        {
            for (int i = 0; i < dtSour.Rows.Count; i++)
            {
                dtDes.ImportRow(dtSour.Rows[i]);
            }
            return dtDes;
        }
        public static DataTable InitTable()
        {
            DataTable dt = new DataTable("TblCategories");
            dt.Columns.AddRange(new DataColumn[] { 
                new DataColumn("ID", typeof(Int32)), 
                new DataColumn("Name", typeof(String)), 
                new DataColumn("NameVN", typeof(String)), 
                new DataColumn("Rank", typeof(Int32)), 
                new DataColumn("LinkedID", typeof(Int32)), 
                new DataColumn("Level", typeof(Int32)), 
                new DataColumn("Status", typeof(Int32)),
                new DataColumn("Image",typeof(String)),
                new DataColumn("Decribes",typeof(String))
            });

            return dt;

        }
        #endregion Method
        /// <summary>
        /// Return DataTable from cate
        /// </summary>
        /// <param name="cate"></param>
        /// <param name="sErr"></param>
        /// <returns></returns>
        public DataTable GetAllChilds(int cate, ref string sErr)
        {
            return _objDAO.GetAllChilds(cate, ref sErr);
        }
        /// <summary>
        /// Return Array CategoryID String
        /// </summary>
        /// <param name="arrCate"></param>
        /// <param name="sErr"></param>
        /// <returns></returns>
        public string GetAllChilds(string arrCate, ref string sErr)
        {
            List<string> result = new List<string>();
            string[] arrTmp = arrCate.Split(',');
            for (int i = 0; i < arrTmp.Length; i++)
            {
                DataTable tmp = GetAllChilds(Convert.ToInt32(arrTmp[i]), ref sErr);
                foreach (DataRow row in tmp.Rows)
                {
                    if (!result.Contains(row["ID"].ToString()))
                        result.Add(row["ID"].ToString());
                }
            }
            return string.Join(",", result.ToArray());
        }
        public DataTable GetLeafsCategories(ref  string sErr)
        {
            return _objDAO.GetLeafsCategories(ref sErr);
        }

        public string GetCateByPro(Int64 idpro, ref string sErr)
        {
            return _objDAO.GetCateByPro(idpro, ref sErr);
        }
        public DataTable GetCateAllByPro(Int64 idpro,string notType, ref string sErr)
        {
            return _objDAO.GetCateAllByPro(idpro, notType, ref sErr);
        }

        public DataTable GetAllParents(int id, ref string sErr)
        {
            return _objDAO.GetAllParents(id, ref sErr);
        }
    }
}
